package com.lyrcsoft;

import com.lyrcsoft.config.AppConfig;
import com.lyrcsoft.services.IUserExtendSerivce;
import com.lyrcsoft.services.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * Advice：通知，就字面意思，但是有2个部分组成，通知内容和通知到哪里去。
 * <p>
 * 通知类型:
 * <p>
 * Before ：前置通知，在连接点方法前调用
 * <p>
 * After ：后置通知，在连接点方法后调用
 * <p>
 * AfterReturning：返回通知，在连接点方法执行并正常返回后调用，要求连接点方法在执行过程中没有发生异常
 * <p>
 * AfterThrowing：异常通知，当连接点方法异常时调用
 * <p>
 * Around：环绕通知，它将覆盖原有方法，但是允许你通过反射调用原有方法，后面会讲
 * <p>
 * Aspect：切面！包括连接点，切点，通知的一个载体。（如果用AspectJ它就是一个类，如果用springXML的时候它就是一个标签）并且交给spring管理。
 * <p>
 * Target object：目标对象，原始对象。
 * <p>
 * AOP proxy：代理对象， 包含了原始对象的代码和增强后的代码的那个对象。
 * <p>
 * 作者：vince_zww
 * 链接：https://www.jianshu.com/p/94879042db88
 * 来源：简书
 * 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
 * <p>
 * https://www.jianshu.com/p/94879042db88
 */
public class App {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
		context.register(AppConfig.class);
		context.refresh();
		// AOP围绕这几个后置处理器
		//BeanPostProcessor==> Bean的后置处理器，
		//		==>postProcessBeforeInitialization 				初始化前后置处理器
		//		==>postProcessAfterInitialization  				初始化后后置处理器
		//InstantiationAwareBeanPostProcessor
		//		==> postProcessProperties  							属性赋值后置处理器
		//		==> postProcessPropertyValues						过期的属性赋值后置处理器（可忽略）
		//		==> postProcessBeforeInstantiation      		实例化前后置处理器
		//		==> postProcessAfterInstantiation        			实例化后后置处理器
		//SmartInstantiationAwareBeanPostProcessor
		//		==> predictBeanType							    		方法的直译，预测Bean类型
		//		==> determineCandidateConstructors  		方法的直译，推断构造方法
		//		==> getEarlyBeanReference                    		为了解决 循环依赖，提前将实例暴露到单例工厂
		Object _o = context.getBean("userService");
		UserService userService = (UserService) context.getBean("userService");
		userService.test();
		IUserExtendSerivce userExtendSerivce = (IUserExtendSerivce) context.getBean("userService");
		userExtendSerivce.doExtend();
	}

}
